package org.javaforever.oville.operator;

import org.javaforever.oville.NarrowWord;
import org.javaforever.oville.NarrowWords;
import org.javaforever.oville.ValidateException;
import org.javaforever.oville.Word;
import org.javaforever.oville.Words;

public class Decode {
	public static NarrowWord decodeNarrowWord(Word source,String varName) throws ValidateException {
		byte [] result = new byte[4];
		byte [] src = source.getWord();
		
		for (int i= 0;i<4;i++) {
			byte bit = src[2*i];
			byte zero = (byte)0;
			byte b7 = (byte) ((bit&0x80)>0?1:0);
			byte b6 = (byte) ((bit&0x40)>0?1:0);
			
			byte b5 = (byte) ((bit&0x20)>0?1:0);
			byte b4 = (byte) ((bit&0x10)>0?1:0);
			
			byte b3 = (byte) ((bit&0x08)>0?1:0);
			byte b2 = (byte) ((bit&0x04)>0?1:0);
			
			byte b1 = (byte)  ((bit&0x02)>0?1:0);
			byte b0 = (byte)  ((bit&0x01)>0?1:0);
			
			byte bit2 = src[2*i+1];

			byte b27 = (byte) ((bit2&0x80)>0?1:0);
			byte b26 = (byte) ((bit2&0x40)>0?1:0);
			
			byte b25 = (byte) ((bit2&0x20)>0?1:0);
			byte b24 = (byte) ((bit2&0x10)>0?1:0);
			
			byte b23 = (byte) ((bit2&0x08)>0?1:0);
			byte b22 = (byte) ((bit2&0x04)>0?1:0);
			
			byte b21 = (byte)  ((bit2&0x02)>0?1:0);
			byte b20 = (byte)  ((bit2&0x01)>0?1:0);
			
			if ((zero |(b7<<7)|(b5<<6)|(b3<<5)|(b1<<4) |(b27<<3)|(b25<<2)|(b23<<1)|b21) != 0) 
				throw new ValidateException("包含量子信息，无法投影到经典域！") ; 
			result[i] = (byte) (zero |(b6<<7)|(b4<<6)|(b2<<5)|(b0<<4) |(b26<<3)|(b24<<2)|(b22<<1)|b20);
		}
		
		NarrowWord nw = new NarrowWord();
		nw.setVarName(varName);
		nw.setNarrowWord(result);
		return nw;
	}
	
	public static NarrowWords decode(Words sources,String varName) throws ValidateException{
		NarrowWords nws = new NarrowWords();
		nws.setVarName(varName);
		for (Word w:sources.getWords()) {
			NarrowWord nw = decodeNarrowWord(w,varName);
			nws.addNarrowWord(nw);
		}
		return nws;
	}
	
	public static NarrowWord decode(Word encoded) {
		return null;
	}
	
	public static void main(String [] argv) throws Exception{
		Word w = new Word();
		byte[] bytes = new byte[8];
		bytes[0] = (byte)0x01;
		bytes[1] = (byte)0x01;
		bytes[2] = (byte)0x01;
		bytes[3] = (byte)0x01;
		bytes[4] = (byte)0x01;
		bytes[5] = (byte)0x01;
		bytes[6] = (byte)0x01;
		bytes[7] = (byte)0x01;
		w.setWord(bytes);
		NarrowWord nw = decodeNarrowWord(w,"word");
		System.out.println(w.toBinStr());
	}
}
